/* Yet Another Copy Program
 * by Peter Justin and Stefan Bauer, ITM12
 *
 * Usage: ./yacp <source> <destination>
 *
 */
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>


int main(int argc, char *argv[]) {

    // we need exactly 2 arguments
    // 3, because the name of the program  is stored in argv[0]
    if(argc != 3) {
        printf("Usage: %s <source> <destination>\n", argv[0]);
        return errno;
    }

    char *source_file = argv[1];
    char *destination_file = argv[2];

    // open the source file as READ ONLY
    int source = open(source_file, O_RDONLY);
    if(source < 0) {
        fprintf(stderr, "Source: open(2) aborted with errno '%d'", errno);
        return errno;
    }

    // open the destination file as WRITE ONLY, CREATE it if it doesn't exist
    // and the O_EXCL ensures that the file doesn't exist
    int destination = open(destination_file, O_WRONLY | O_CREAT | O_EXCL, 0666);
    if(destination < 0) {
        fprintf(stderr, "Destination: open(2) aborted with errno: '%d'\n", errno);
        return errno;
    }

    // writing file here
    char buffer[2048];
    while(1) {
        // read the bytes from the source file and store the amount of bytes
        // read in the read_bytes variable. It is needed to let write() know
        // how many bytes are read.
        int read_bytes = read(source, &buffer, 2048);

        // read returns 0 if no bytes are read and therefore we do not need
        // to write any bytes --> exit the loop
        if(read_bytes == 0) {
            break;
        }

        // read returns -1 if an error occured and sets the errno accordingly
        if(read_bytes < 0) {
            fprintf(stderr, "read(2) aborted with errno: '%d'\n", errno);
            return errno;
        }


        // now only write the counted bytes from read_bit
        int written_bytes = write(destination, &buffer, read_bytes);

        // no need to check if written_bytes == 0 because if no bytes are read
        // (see read(2)), no bytes can be written.
        // written_bytes == 0 could also be a failure. See write(2) for more
        // information

        // an error occured while writing the file
        if(written_bytes < 0) {
            fprintf(stderr, "write(2) aborted with errno: '%d',\n", errno);
            // delete the file from the filesystem
            unlink(destination_file);
            return errno;
        }
    }

    return 0;
}
